package com.hundsun.aitest.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.hundsun.aitest.common.ApiPlatformConfig;
import com.hundsun.aitest.common.CasePriorityEnum;
import com.hundsun.aitest.common.CaseTypeEnum;
import com.hundsun.aitest.model.ai.AutoCase;
import com.hundsun.aitest.model.ai.TestParameters;
import com.hundsun.aitest.model.ai.TestPoint;
import com.hundsun.aitest.model.plat.ApiParams;
import com.hundsun.aitest.model.plat.InterfaceDict;
import com.hundsun.aitest.service.AutoCaseParser;
import com.hundsun.aitest.service.BaoSongDBService;
import com.hundsun.aitest.util.JsonContentExtractor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.hundsun.aitest.common.Constants.CHECK_INTERFACE_NAME;

@Service
@Slf4j
public class AutoCaseParserImpl implements AutoCaseParser<AutoCase> {
    @Autowired
    BaoSongDBService baoSongDBService;

    @Autowired
    private ApiPlatformConfig apiPlatformConfig;

    @Override
    public AutoCase parse(String jsonString,int type,String attachInfo) {
        // Extract the JSON content from the string
        String jsonContent = JsonContentExtractor.extractJsonContent(jsonString);

        log.info("排除后的json内容：\n {}",jsonContent);
        // Parse the extracted JSON content
        try {
            JSONObject jsonObject = JSON.parseObject(jsonContent);
            return parseJsonObject(jsonObject, CaseTypeEnum.fromValue(type), attachInfo);
        } catch (JSONException e) {
            // 解析json string 异常
            //System.err.println("Error parsing JSON: " + e.getMessage());
            log.error("解析大模型返回的json异常,输入的jsonString内容：\n {}",jsonContent,e);
            return null;
        }
    }

    private AutoCase parseJsonObject(JSONObject jsonObject, CaseTypeEnum type, String attachInfo) throws JSONException {
        switch (type) {
            case AUTO:
                return parseJsonObject(jsonObject);
            case CHECK:
                return parseCheckCase(jsonObject,attachInfo);
            default:
                throw new IllegalArgumentException("Unsupported case type: " + type.getDescription());
        }
    }

    private AutoCase parseCheckCase(JSONObject jsonObject, String attachInfo) {
        AutoCase autoCase = new AutoCase();
        //勾稽的接口先确定
        autoCase.setInterfaceName(CHECK_INTERFACE_NAME);

        // 遍历 jsonObject 的所有键值对
        List<TestPoint> testPoints = new ArrayList<>();

        // 定义常量
        final String CASE_PRIORITY = "P2";
        //固定成odbc的数据库链接
        final String DB_CONNECTION = "odbc";
        final String CASE_TYPE_POSITIVE = "正例";
        final String CASE_TYPE_NEGATIVE = "反例";
        final String TEST_RESULT_PASS = "勾稽验证通过";
        final String TEST_RESULT_FAIL = "勾稽验证不通过";

        for (String key : jsonObject.keySet()) {
            String value = (String) jsonObject.get(key);
//            //如果sql是空，说明该反例的数据无法构造生成自动化用例，该场景跳过。
//            if(value.equals("")){
//                continue;
//            }
            String caseType = CASE_TYPE_POSITIVE;
            String testResult = TEST_RESULT_PASS;

            // attachInfo为勾稽的checkCode
            String testPurpose = attachInfo + "-" + key;
            String priority = CASE_PRIORITY;
            String checkRuleDescription = baoSongDBService.getCheckName(attachInfo);
            //如果勾稽规则标注为严重，则用例设置为P1级别
            if(checkRuleDescription.contains("严重")){
                priority="P1";
            }

            // preSql 值等于 jsonObject 中的值
            String preSql = value;

            if (!key.contains(CASE_TYPE_POSITIVE)) {
                caseType = CASE_TYPE_NEGATIVE;
                testResult = TEST_RESULT_FAIL;
            }

            // Todo 先写死，后续动态设置
            String dbConnection = DB_CONNECTION;

            // 针对接口checkReportDataAsync来设置参数,分为3步：1，报送发起。2，勾稽校验。3，勾稽结果校验
            Map<String, Object> paramMap = new HashMap<>();
            //勾稽检查接口的参数：
            paramMap=baoSongDBService.getCheckRuleInterParams(attachInfo);
            TestParameters params = new TestParameters(paramMap);

            TestPoint testPoint = new TestPoint(
                    testPurpose,
                    params,
                    testResult,
                    caseType,
                    priority,
                    preSql,
                    dbConnection
            );

            testPoints.add(testPoint);
        }

        // 设置测试点到 AutoCase
        autoCase.setTestPoints(testPoints);

        return autoCase;
    }

    private AutoCase parseJsonObject(JSONObject jsonObject) {
        AutoCase autoCase = new AutoCase();

        String urlPath = jsonObject.getString("interface");

        // Parse the interface name
        autoCase.setInterfaceName(jsonObject.getString("interface"));

        // Parse the keys (test points)
        List<JSONObject> keys = jsonObject.getJSONArray("keys").toJavaList(JSONObject.class);
        List<TestPoint> testPoints = new ArrayList<>();
        for (JSONObject key : keys) {
            String testPurpose = key.getString("测试目的");
            JSONObject parameters = key.getJSONObject("接口参数");
            String testResult = key.getString("测试结果");
            String caseSlideType = key.getString("正反例");
            String casePriority = key.getString("优先级");
            casePriority = CasePriorityEnum.isValidPriorityCode(casePriority) ? casePriority : "P2";
            // 添加前置条件，执行sql预埋数据
            String prepareSql = key.getString("前置预埋数据");
            String afterSql = key.getString("后置数据清理");
            String odbcLink = "odbc";
            if(prepareSql.isEmpty()){prepareSql = null;odbcLink=null;}
            // Convert the parameters to a Map<String, Object>
            Map<String, Object> paramMap = new HashMap<>();
            //预期值根据预计结果参数设置
            JSONArray resultMap = key.getJSONArray("预计结果参数");
            List<String> expectValueList = new ArrayList<>();
            expectValueList.add("resp_status_code=200");
            for (int i = 0; i < resultMap.size(); i++) {
                //String paramName = resultMap.getJSONObject(i).getString("name");
                String paramValue = resultMap.getJSONObject(i).getString("value");
                String path= resultMap.getJSONObject(i).getString("path");
                if(path==null||"".equals(path)){
                    continue;
                }
                String expectValue = path.replace("/","_").substring(1, path.length());
                expectValue=expectValue+"="+paramValue;
                expectValueList.add(expectValue);
            }
            paramMap.put("期望",String.join(";",expectValueList));
            for (String paramName : parameters.keySet()) {
                paramMap.put(paramName, parameters.get(paramName));
            }
            // 根据urlPath获取缓存中的接口字典信息，设置默认值
            InterfaceDict interfaceDictTemp = apiPlatformConfig.queryInterfaceDict(urlPath);
            if (interfaceDictTemp != null) {
                ApiParams reqFormatter = interfaceDictTemp.getReqFormatter();
                if (reqFormatter != null) {paramMap.put(reqFormatter.getName(), reqFormatter.getDefaultValue());}
            }
            TestParameters params = new TestParameters(paramMap);
            TestPoint testPoint = new TestPoint(testPurpose,params,testResult,
                    caseSlideType,casePriority,prepareSql,odbcLink, afterSql);
            testPoints.add(testPoint);
        }

        autoCase.setTestPoints(testPoints);
        autoCase.setCaseType("1");
        log.info("大模型返回string的解析结果,autoCase={}",autoCase);
        return autoCase;
    }
}